package org.deltaset.meta.internal;

import org.deltaset.meta.Finder;
import java.util.ArrayList;
import org.deltaset.meta.annotation.DsFirstResult;
import org.deltaset.meta.annotation.DsMaxResult;
import java.util.List;
import static org.junit.Assert.*;

/**
 *
 * @author dmakariev
 */
abstract class AbstractFinderTestBase {

    protected abstract Finder finder();

    protected void assertPage(final int firstResult, final int maxResult, final int expectedPageSize) {
        final List<Object> page = page(firstResult, maxResult);
        final int pageSize = page.size();
        final String pageTestName = "page(firstResult=" + firstResult + ",maxResult=" + maxResult + "):";
        assertEquals(pageTestName + "size ", expectedPageSize, pageSize);
        assertEquals(pageTestName + "first element name", "id" + firstResult, ((SomeEntity) page.get(0)).getName());
        assertEquals(pageTestName + "last element name", "id" + (firstResult + expectedPageSize - 1), ((SomeEntity) page.get(pageSize - 1)).getName());
    }

    private List<Object> page(final int firstResult, final int maxResult) {
        final Finder pagedFinderWithCounter = finder();
        return pagedFinderWithCounter.finder(firstResult, maxResult);

    }

    protected static class SomeEntity {

        private final String name;

        public SomeEntity(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    protected static class ListService {

        public ListService() {
        }
        private static final List<SomeEntity> allRecords = new ArrayList<SomeEntity>();

        static {
            for (int i = 0; i < 100; i++) {
                allRecords.add(new SomeEntity("id" + i));
            }
        }

        public Long countAll() {
            return Long.valueOf(allRecords.size());
        }

        public List<SomeEntity> findAll() {
            return allRecords;
        }

        public List<SomeEntity> findAll(@DsFirstResult int firstResult, @DsMaxResult int maxResult) {
            return findAllException(firstResult, maxResult);
        }

        public List<SomeEntity> findAllException(int firstResult, int maxResult) {
            final int calculatedToIndex = firstResult + maxResult;
            final int allRecordsSize = allRecords.size();
            final int toIndex = (calculatedToIndex < allRecordsSize) ? calculatedToIndex : allRecordsSize;
            return allRecords.subList(firstResult, toIndex);
        }
    }
}
